#include "io_thread.h"
#include "sock.h"
#include "cconf.h"
#include <pthread.h>
#include <signal.h>

struct cconf_io_thread_s {
	pthread_t thread_id;
	cconf_message_callback_fcn_t msg_cb;
	void * msg_cb_arg;
	void * sock;
};

static void * _io_thread(void * arg)
{
	cconf_io_thread_t * i = arg;
	char * in, * out;
	
	while (1)
	{
		in = cconf_sock_get_string(i->sock);
		
		if (in == NULL)
			return NULL;
		
		if (i->msg_cb)
			i->msg_cb(&out, in, i->msg_cb_arg);		
		else
			asprintf(&out, "poopy");
		cconf_sock_send_string(i->sock, out);
		free(in);
		free(out);
	}
	
	return NULL;
}

cconf_io_thread_t * cconf_io_thread_create(char * sockname, cconf_message_callback_fcn_t msg_cb, void * cb_arg)
{
	int result;
	sigset_t newsig, oldsig;
	cconf_io_thread_t * i = calloc(1, sizeof(cconf_io_thread_t));
	if (!i) return NULL;
	
	i->msg_cb = msg_cb;
	i->msg_cb_arg = cb_arg;
	
	sigfillset(&newsig);
	pthread_sigmask(SIG_BLOCK, &newsig, &oldsig);
	
	i->sock = cconf_sock_create(sockname, CCONF_SOCK_SERVER);
	result = pthread_create(&i->thread_id, NULL, _io_thread, i);
	
	pthread_sigmask(SIG_SETMASK, &oldsig, NULL);
	
	if (result != 0)
	{
		free(i);
		return NULL;
	}
	
	pthread_detach(i->thread_id);
	return i;
}

void cconf_io_thread_finish(cconf_io_thread_t * i)
{
	pthread_cancel(i->thread_id);
	cconf_sock_destroy(i->sock);
	free(i);
}
